package handler

import (
	"net/http"

	"database/sql"

	"gitee.com/hp-huiw/family-expense-api/internal/service"
	"github.com/gin-gonic/gin"
)

type AccountGroupUserHandler interface {
	QueryAvailableAccountGroups(ctx *gin.Context)
	Remove(ctx *gin.Context)
	Quit(ctx *gin.Context)
}

func NewAccountGroupUserHandler(db *sql.DB) AccountGroupUserHandler {
	return &accountGroupUserHandler{
		accountGroupUserService: service.NewAccountGroupUserService(db),
	}
}

// Matches /query-available-account-groups of http get action.
func (h *accountGroupUserHandler) QueryAvailableAccountGroups(ctx *gin.Context) {
	c := ctx.Request.Context()
	userID := GetClaims(ctx).UserID
	result, err := h.accountGroupUserService.QueryAvailableAccountGroups(c, userID)

	if err != nil {
		ctx.Error(err)
		return
	}

	SendDataResponse(ctx, result)
}

// Matches /remove of http post action.
func (h *accountGroupUserHandler) Remove(ctx *gin.Context) {
	var postedData struct {
		UserID   string `json:"userID"`
		Username string `json:"username"`
	}

	if err := ctx.ShouldBindJSON(&postedData); err != nil {
		ctx.Error(err)
		return
	}

	c := ctx.Request.Context()
	userID := postedData.UserID
	username := postedData.Username
	accountGroupID := GetClaims(ctx).AccountGroupID
	err := h.accountGroupUserService.Remove(c, accountGroupID, userID, username)

	if err != nil {
		ctx.Error(err)
		return
	}

	SendStatusResponse(ctx, http.StatusNoContent)
}

// Matches /quit of http post action.
func (h *accountGroupUserHandler) Quit(ctx *gin.Context) {
	var postedData struct {
		AccountGroupID string `json:"accountGroupID"`
	}

	if err := ctx.ShouldBindJSON(&postedData); err != nil {
		ctx.Error(err)
		return
	}

	c := ctx.Request.Context()
	accountGroupID := postedData.AccountGroupID
	claim := GetClaims(ctx)
	userID := claim.UserID
	username := claim.Username
	err := h.accountGroupUserService.Remove(c, accountGroupID, userID, username)

	if err != nil {
		ctx.Error(err)
		return
	}

	SendStatusResponse(ctx, http.StatusNoContent)
}

// Container of AccountGroupUserHandler functions.
type accountGroupUserHandler struct {
	accountGroupUserService service.AccountGroupUserService
}
